package com.shadow.demo.ip.client2;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;

@Slf4j
@Service
public class ClientHandler {

    @Resource
    private RestTemplate restTemplate;

    @Value("${spring.profiles.active}")
    private String active;

    @Value("${ip.base}")
    private String base;

    @Value("${ip.local.enable}")
    private boolean localEnable;
    
    @Value("${ip.remote.enable}")
    private boolean publicEnable;

    @Scheduled(cron = "${ip.local.cron}")
    public void local() {
        if (localEnable) {
            String ip = getAppAddressInfo();
            String localHostName = getLocalHostName();
            log.info("{} ip : {}", localHostName, ip);
            String url = base + "ip/public/register/" + active + "/" + ip;
            String body = register(url);
            log.info("registerLocal result body : {}", body);
        }
    }
    
    @Scheduled(cron = "${ip.remote.cron}")
    public void getIp() {
        if (publicEnable) {
            String url = base + "ip/public/register/" + active + "/0.0.0.0";
            String body = register(url);
            log.info("registerRemote result body : {}", body);
        }
    }

    private String register(final String url) {
        ResponseEntity<String> result = restTemplate.getForEntity(
                url,
                String.class
        );
        return result.getBody();
    }

    /**
     * 获取本机机器名
     * */
    private static String getLocalHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            log.error("获取本机机器名异常", e);
        }
        return null;
    }

    /**
     * 获取本地ip
     * */
    private static String getAppAddressInfo() {
        StringBuilder ipAddress = new StringBuilder();
        Boolean isFirst = Boolean.TRUE;
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    InetAddress inetAddress = inetAddresses.nextElement();
                    if (!inetAddress.isLoopbackAddress() &&
                            !inetAddress.isLinkLocalAddress()
                            && inetAddress.isSiteLocalAddress()
                    ) {
                        String hostAddress = inetAddress.getHostAddress();
                        if (Boolean.FALSE.equals(isFirst)) {
                            ipAddress.append(",");
                        }
                        ipAddress.append(hostAddress);
                        isFirst = Boolean.FALSE;
                    }
                }
            }
        } catch (SocketException e) {
            log.error("获取ip异常", e);
        }
        return ipAddress.toString();
    }
}
